package com.ssm.sport.controller;

import com.ssm.sport.dto.ResultDTO;
import com.ssm.sport.entity.User;
import com.ssm.sport.entity.Shipping;
import com.ssm.sport.service.UserService;
import com.ssm.sport.service.ShippingService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用户控制器
 */
@Controller
@RequestMapping("/user")
public class UserController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    
    // 验证码存储，生产环境应该使用Redis等缓存服务
    private static final Map<String, SmsCodeInfo> SMS_CODE_CACHE = new ConcurrentHashMap<>();
    
    // 验证码有效期（毫秒）
    private static final long SMS_CODE_EXPIRE = 5 * 60 * 1000;

    @Autowired
    private UserService userService;

    @Autowired
    private ShippingService shippingService;

    /**
     * 用户登录
     */
    @PostMapping("/login")
    @ResponseBody
    public ResultDTO<?> login(String username, String password, HttpSession session) {
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            return ResultDTO.failure("用户名或密码不能为空");
        }

        User user = userService.login(username, password);
        if (user == null) {
            return ResultDTO.failure("用户名或密码错误");
        }

        // 将用户信息存入session
        session.setAttribute("user", user);
        return ResultDTO.success(user, "登录成功");
    }
    
    /**
     * 发送短信验证码
     */
    @PostMapping("/send-code")
    @ResponseBody
    public ResultDTO<?> sendVerificationCode(@RequestParam String phone) {
        if (StringUtils.isBlank(phone)) {
            return ResultDTO.failure("手机号不能为空");
        }
        
        // 验证手机号格式
        if (!phone.matches("^1[3-9]\\d{9}$")) {
            return ResultDTO.failure("手机号格式不正确");
        }
        
        // 检查是否频繁发送
        SmsCodeInfo existingCode = SMS_CODE_CACHE.get(phone);
        if (existingCode != null && System.currentTimeMillis() - existingCode.getSendTime() < 60000) {
            return ResultDTO.failure("请求过于频繁，请稍后再试");
        }
        
        // 生成6位随机验证码
        String code = generateRandomCode(6);
        
        // 在实际应用中，这里应该调用SMS服务发送验证码
        logger.info("为手机号 {} 生成验证码: {}", phone, code);
        
        // 将验证码保存到缓存
        SMS_CODE_CACHE.put(phone, new SmsCodeInfo(code, System.currentTimeMillis()));
        
        return ResultDTO.success(null, "验证码已发送");
    }
    
    /**
     * 短信验证码登录
     */
    @PostMapping("/sms-login")
    @ResponseBody
    public ResultDTO<?> smsLogin(@RequestParam String phone, @RequestParam String code, HttpSession session) {
        if (StringUtils.isBlank(phone) || StringUtils.isBlank(code)) {
            return ResultDTO.failure("手机号和验证码不能为空");
        }
        
        // 验证手机号格式
        if (!phone.matches("^1[3-9]\\d{9}$")) {
            return ResultDTO.failure("手机号格式不正确");
        }
        
        // 验证码校验
        SmsCodeInfo smsCodeInfo = SMS_CODE_CACHE.get(phone);
        if (smsCodeInfo == null) {
            return ResultDTO.failure("验证码不存在或已过期");
        }
        
        // 检查验证码是否过期
        if (System.currentTimeMillis() - smsCodeInfo.getSendTime() > SMS_CODE_EXPIRE) {
            SMS_CODE_CACHE.remove(phone);
            return ResultDTO.failure("验证码已过期，请重新获取");
        }
        
        // 检查验证码是否正确
        if (!smsCodeInfo.getCode().equals(code)) {
            return ResultDTO.failure("验证码错误");
        }
        
        // 验证通过后，移除验证码
        SMS_CODE_CACHE.remove(phone);
        
        // 查找用户，如果不存在则自动注册
        User user = userService.getByPhone(phone);
        if (user == null) {
            // 自动注册
            user = new User();
            user.setUsername(phone); // 使用手机号作为用户名
            user.setPhone(phone);
            // 生成随机密码，实际应用中可能会发送短信告知用户
            String randomPassword = generateRandomCode(8);
            user.setPassword(randomPassword); // 服务层会进行MD5加密
            
            if (!userService.register(user)) {
                return ResultDTO.failure("登录失败，请稍后再试");
            }
            
            // 重新获取完整的用户信息
            user = userService.getByPhone(phone);
        }
        
        // 检查用户状态
        if (user.getStatus() != null && user.getStatus() == 0) {
            return ResultDTO.failure("账号已被禁用，请联系客服");
        }
        
        // 将用户信息存入session
        user.setPassword(null); // 清除密码信息
        session.setAttribute("user", user);
        
        return ResultDTO.success(user, "登录成功");
    }

    /**
     * 用户注册
     */
    @PostMapping("/register")
    @ResponseBody
    public ResultDTO<?> register(
            @RequestParam String username,
            @RequestParam String password,
            @RequestParam(required = false) String email,
            @RequestParam(required = false) String phone,
            @RequestParam(required = false) String realName,
            @RequestParam(required = false) String gender,
            @RequestParam(required = false) String address) {
        
        logger.info("Received registration request for username: {}", username);
        
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            logger.warn("Registration failed: username or password is blank");
            return ResultDTO.failure("用户名或密码不能为空");
        }

        if (userService.checkUsername(username)) {
            logger.warn("Registration failed: username already exists: {}", username);
            return ResultDTO.failure("用户名已存在");
        }
        
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setEmail(email);
        user.setPhone(phone);
        user.setRealName(realName);
        
        // 处理性别字段
        if (StringUtils.isNotBlank(gender)) {
            try {
                user.setGender(Integer.parseInt(gender));
            } catch (NumberFormatException e) {
                logger.warn("Invalid gender format: {}", gender);
                // 默认为保密
                user.setGender(0);
            }
        } else {
            // 默认为保密
            user.setGender(0);
        }
        
        user.setAddress(address);

        if (userService.register(user)) {
            logger.info("User registered successfully: {}", username);
            return ResultDTO.success(null, "注册成功");
        } else {
            logger.error("Registration failed for username: {}", username);
            return ResultDTO.failure("注册失败");
        }
    }

    /**
     * 退出登录
     */
    @GetMapping("/logout")
    public String logout(HttpSession session) {
        session.removeAttribute("user");
        return "redirect:/";
    }

    /**
     * 检查用户是否登录
     */
    @GetMapping("/check_login")
    @ResponseBody
    public ResultDTO<?> checkLogin(HttpSession session) {
        User user = (User) session.getAttribute("user");
        if (user != null) {
            return ResultDTO.success(user);
        }
        return ResultDTO.failure("用户未登录");
    }

    /**
     * 获取用户信息
     */
    @GetMapping("/info")
    @ResponseBody
    public ResultDTO<?> getUserInfo(HttpSession session) {
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return ResultDTO.failure("用户未登录");
        }
        
        // 从数据库获取最新的用户信息
        User latestUser = userService.getById(user.getId());
        if (latestUser != null) {
            latestUser.setPassword(null);
            session.setAttribute("user", latestUser);
            return ResultDTO.success(latestUser);
        }
        
        return ResultDTO.failure("获取用户信息失败");
    }

    /**
     * 更新用户信息
     */
    @PostMapping("/update")
    @ResponseBody
    public ResultDTO<?> updateUserInfo(@RequestBody User user, HttpSession session) {
        User currentUser = (User) session.getAttribute("user");
        if (currentUser == null) {
            return ResultDTO.failure("用户未登录");
        }
        
        // 获取数据库中的最新用户信息
        User dbUser = userService.getById(currentUser.getId());
        if (dbUser == null) {
            return ResultDTO.failure("用户不存在");
        }
        
        // 只更新不为null的字段
        if (user.getRealName() != null) {
            dbUser.setRealName(user.getRealName());
        }
        if (user.getEmail() != null) {
            dbUser.setEmail(user.getEmail());
        }
        if (user.getPhone() != null) {
            dbUser.setPhone(user.getPhone());
        }
        if (user.getGender() != null) {
            dbUser.setGender(user.getGender());
        }
        
        // 保持原有的状态和角色
        dbUser.setStatus(1);
        dbUser.setRole(0);
        
        if (userService.updateById(dbUser)) {
            // 更新session中的用户信息
            dbUser.setPassword(null);
            session.setAttribute("user", dbUser);
            return ResultDTO.success(dbUser, "更新成功");
        }
        
        return ResultDTO.failure("更新失败");
    }

    /**
     * 个人中心页面
     */
    @GetMapping("/profile")
    public String profile(Model model, HttpSession session) {
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return "redirect:/login";
        }
        
        // 获取最新的用户信息
        user = userService.getById(user.getId());
        if (user != null) {
            user.setPassword(null);
            model.addAttribute("user", user);
            
            // 获取用户的收货地址列表
            List<Shipping> shippingAddresses = shippingService.getByUserId(user.getId());
            model.addAttribute("shippingAddresses", shippingAddresses);
        }
        
        return "user/profile";
    }

    /**
     * 修改密码
     */
    @PostMapping("/password")
    @ResponseBody
    public ResultDTO<?> updatePassword(String oldPassword, String newPassword, HttpSession session) {
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return ResultDTO.failure("用户未登录");
        }
        
        // 验证原密码
        String md5OldPassword = DigestUtils.md5DigestAsHex(oldPassword.getBytes());
        User dbUser = userService.getById(user.getId());
        if (!md5OldPassword.equals(dbUser.getPassword())) {
            return ResultDTO.failure("原密码错误");
        }
        
        // 更新密码
        String md5NewPassword = DigestUtils.md5DigestAsHex(newPassword.getBytes());
        dbUser.setPassword(md5NewPassword);
        if (userService.updateById(dbUser)) {
            // 更新成功后清除session，要求用户重新登录
            session.removeAttribute("user");
            return ResultDTO.success(null, "密码修改成功");
        }
        
        return ResultDTO.failure("密码修改失败");
    }
    
    /**
     * 修改密码（替代接口）
     */
    @PostMapping("/update-password")
    @ResponseBody
    public ResultDTO<?> updatePasswordAlternate(String oldPassword, String newPassword, HttpSession session) {
        // 调用现有的密码更新逻辑
        return updatePassword(oldPassword, newPassword, session);
    }
    
    /**
     * 生成随机验证码
     * @param length 验证码长度
     * @return 随机验证码
     */
    private String generateRandomCode(int length) {
        StringBuilder code = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }
    
    /**
     * 短信验证码信息类
     */
    private static class SmsCodeInfo {
        private final String code;
        private final long sendTime;
        
        public SmsCodeInfo(String code, long sendTime) {
            this.code = code;
            this.sendTime = sendTime;
        }
        
        public String getCode() {
            return code;
        }
        
        public long getSendTime() {
            return sendTime;
        }
    }
} 